#version 330 core

in vec2 UV;
in vec3 Position_worldspace;
in vec3 Normal_cameraspace;
in vec3 EyeDirection_cameraspace;
in vec3 LightDirection_cameraspace;
in vec4 ShadowCoord;

out vec3 color;

uniform sampler2D Texture1;
uniform mat4 MV;
uniform int TypeObject;
uniform sampler2DShadow shadowMap;

vec2 poissonDisk[16] = vec2[]( 
   vec2( -0.94201624, -0.39906216 ), 
   vec2( 0.94558609, -0.76890725 ), 
   vec2( -0.094184101, -0.92938870 ), 
   vec2( 0.34495938, 0.29387760 ), 
   vec2( -0.91588581, 0.45771432 ), 
   vec2( -0.81544232, -0.87912464 ), 
   vec2( -0.38277543, 0.27676845 ), 
   vec2( 0.97484398, 0.75648379 ), 
   vec2( 0.44323325, -0.97511554 ), 
   vec2( 0.53742981, -0.47373420 ), 
   vec2( -0.26496911, -0.41893023 ), 
   vec2( 0.79197514, 0.19090188 ), 
   vec2( -0.24188840, 0.99706507 ), 
   vec2( -0.81409955, 0.91437590 ), 
   vec2( 0.19984126, 0.78641367 ), 
   vec2( 0.14383161, -0.14100790 ) 
);

void main(){

	vec3 LightColor = vec3(1,1,1);
	float LightPower = 1.0f;
	int lobe = 5;
	
	// Material
	vec3 DiffuseColor;
	if (TypeObject == 0) {
		DiffuseColor = vec3(0.75,0.75,0.75);
	}
	else if (TypeObject == 1){
		DiffuseColor = texture( Texture1, UV ).rgb;
	}
    else {
        DiffuseColor = vec3(0.0f,0.0f,0.0f);
    }
	 
	vec3 AmbientColor = vec3(0.2,0.2,0.2) * DiffuseColor;
	vec3 SpecularColor = vec3(0.3,0.3,0.3);

	vec3 n = normalize( Normal_cameraspace );
	vec3 l = normalize( LightDirection_cameraspace );

	float cosTheta = clamp( dot( n,l ), 0,1 );
	
	vec3 E = normalize(EyeDirection_cameraspace);
	vec3 R = reflect(-l,n);

	float cosAlpha = clamp( dot( E,R ), 0,1 );
	
	float visibility=1.0;
	float bias = 0.005;

	// Sample the shadow map
	for (int i=0;i<5;i++){
		visibility -= 0.2*(1.0-texture( shadowMap, vec3(ShadowCoord.xy + poissonDisk[i]/700.0,  (ShadowCoord.z-bias)/ShadowCoord.w) ));
	}

	//visibility -= (1.0-texture( shadowMap, vec3(ShadowCoord.xy,  (ShadowCoord.z-bias)/ShadowCoord.w) ));
	
	color = 
		// Ambient : simulates indirect lighting
		AmbientColor +
		// Diffuse : "color" of the object
		visibility * DiffuseColor * LightColor * LightPower * cosTheta+
		// Specular : reflective highlight, like a mirror
		visibility * SpecularColor * LightColor * LightPower * pow(cosAlpha,lobe);

}